package org.jsbd.boss.util;


import java.io.*;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AesUtils {
	
	public static final Logger LOGGER = LoggerFactory.getLogger(AesUtils.class);

    private static final String TAG = AesUtils.class.getSimpleName();
    private static final String AES_KEY = "10a7fc7b1c3d52a25b889a78b6c98b0e";
    private static final byte[] AES_IV  = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,0x0a,0x0b, 0x0c, 0x0d, 0x0e, 0x0f};


    /**
     * 加密
     * @author <a href="mailto:zhouchao@zhexinit.com" >周超</a>
     * @param sSrc
     * @param sKey
     * @param ivs
     * @return
     * @throws Exception
     */
    public static String encrypt(String sSrc,String sKey,String ivs) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] raw = sKey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        // 使用CBC模式，需要一个向量iv，可增加加密算法的强度
        IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
        // 此处使用BASE64做转码。
        return Base64.encodeBase64String(encrypted);
    }

    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            String curByteString = hexString.substring(i * 2, i * 2 + 2);
            d[i] = (byte)(Integer.parseInt(curByteString, 16) & 0xFF);
        }
        return d;
    }

    public static boolean isZipFile(String zipFilePath){
        long zipMagic = 0x04034B50;
        try{
            FileInputStream fileInputStream = new FileInputStream(zipFilePath);
            byte[] readMagic = new byte[4];
            int readLen = fileInputStream.read(readMagic, 0, 4);
            if(4 != readLen){
                return false;
            }

            long readParseMagic = readMagic[0] | (readMagic[1] << 8) | (readMagic[2] << 16) | (readMagic[3] << 24);
            return (readParseMagic == zipMagic);
        }catch (Exception e){
            e.printStackTrace();
        }

        return false;
    }

    public static boolean encryptBigFile(String srcPath, String dstPath){
        try{
            byte[] aseKey = hexStringToBytes(AES_KEY);
            Cipher encrypCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec skeySpec = new SecretKeySpec(aseKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(AES_IV);
            encrypCipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            FileInputStream fileInputStream = new FileInputStream(srcPath);
            FileOutputStream fileOutputStream = new FileOutputStream(dstPath);
            OutputStream out = new CipherOutputStream(fileOutputStream, encrypCipher);

            int readCnt = 0;
            byte[] readBuf = new byte[1024];
            while((readCnt = fileInputStream.read(readBuf)) != -1){
                out.write(readBuf, 0, readCnt);
            }
            out.close();
            fileInputStream.close();
            fileOutputStream.close();

            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }


    public static byte[] encryptBigFile(byte[] datas){
        try{
            byte[] aseKey = hexStringToBytes(AES_KEY);
            Cipher encrypCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec skeySpec = new SecretKeySpec(aseKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(AES_IV);
            encrypCipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);


            InputStream fileInputStream =  new ByteArrayInputStream(datas);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            CipherOutputStream cipherOutputStream = new CipherOutputStream(bos, encrypCipher);
            int readCnt = 0;
            byte[] readBuf = new byte[1024];
            while((readCnt = fileInputStream.read(readBuf)) != -1){
                cipherOutputStream.write(readBuf, 0, readCnt);
            }
            cipherOutputStream.close();
            fileInputStream.close();
            return bos.toByteArray();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static boolean decryptBigFile(String srcPath, String dstPath){
        try{
            byte[] aseKey = hexStringToBytes(AES_KEY);
            Cipher encrypCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec skeySpec = new SecretKeySpec(aseKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(AES_IV);
            encrypCipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

            FileInputStream fileInputStream = new FileInputStream(srcPath);
            FileOutputStream fileOutputStream = new FileOutputStream(dstPath);
            InputStream in = new CipherInputStream(fileInputStream, encrypCipher);

            int readCnt = 0;
            byte[] readBuf = new byte[1024];
            while((readCnt = in.read(readBuf)) != -1){
                fileOutputStream.write(readBuf, 0, readCnt);
            }
            fileOutputStream.close();
            fileInputStream.close();
            in.close();

            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }


    public static byte[] decryptBigFile(byte[] datas){
        try{
            byte[] aseKey = hexStringToBytes(AES_KEY);
            Cipher encrypCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec skeySpec = new SecretKeySpec(aseKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(AES_IV);
            encrypCipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);


            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            InputStream fileInputStream =  new ByteArrayInputStream(datas);
            InputStream in = new CipherInputStream(fileInputStream, encrypCipher);

            int readCnt = 0;
            byte[] readBuf = new byte[1024];
            while((readCnt = in.read(readBuf)) != -1){
                bos.write(readBuf, 0, readCnt);
            }
            bos.close();
            fileInputStream.close();
            in.close();
            return bos.toByteArray();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 
     * 解密
     * @author <a href="mailto:zhouchao@zhexinit.com" >周超</a>
     * @param sSrc
     * @param key
     * @param ivs
     * @return
     * @throws Exception
     */
	public static String decrypt(String sSrc,String key,String ivs) throws Exception {
        try {
            byte[] raw = key.getBytes("UTF-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 =Base64.decodeBase64(sSrc);
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original, "utf-8");
            return originalString;
        } catch (Exception e) {
           LOGGER.error("decrypt error[{}]",e.getMessage(),e);
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
		String data="CaTt2WHT8C0K+vtU5a6yjqJKdVES1FiA6grmOHBWir9cIzFsoFg6CBg3axttAcmawQFlsVIJdpmoLsL17oB9dm8VjWiCAiIDa63ukX7tooVQvUhFUEOugVIoYShopXw8v5CxyK2+zQrkj19Gt1yRsDOWRSChHEeR7ixKYWRHnYNyjoWjAnL+OM2OryB8lgBK7n7sQo3IdSXoI4K/Zc7Nlgu4eYXHMuSA6LCZtqflTqqesrS7cvMkuyY7DQNPb83WZOgrwWpn4iMafdUkzwjTLe3iz8XhkvqtUUC2lb74HqJB7VoWCvbk5gM9hfDiSiGmpNVp4F5rjzlXh5jwMy/J82GZwmX5vTeIqlZK3qOsbwK7O1gGbs9QFjqayuT9M1qTYL+9g2LiRqd+QW3wMrn7AS9wfqAAMPHfGJy6Uytp3/UmAFXKXWxMsNcsUlUKkXo+AVbUF67D4b0yoSF/u7tWHhqScM5+o8zl6369B/B/H177DHJwsNWGlwYlOZq87jCsQu9+X0FYMtGy/tDbpgerZqztUgusHOJV/3T/69NpCLkO1prdDZkCxxcxXuya5GDhphYRuDyLlDrcRvbPm435/hI9yoJwINHtnwBbjQwKDigURdF/w7W0Lcco9yB8x2zElAxgoyb98jFm4xCXZSqae6O7NBI1E9f5muzrVPohQgMtc35iJmPEzP2CQdYivkBiZHSartl6JXDkVRdrDiEVaKDtkaoZpcjONN1M6DNQlJc/uQmVm1xAgDYAcL8R3Woe9k2g7n83aRF7pKbzHSvgrI5oaS6KuNgWoC274PjxLQPPEbY8GEZJkL1SfS5ZkH0DOTstuxujSp+9aSvzY9sQR/HCpAE3lDlKTGALujqAIk8LbpLiRrYmYt/20TAOYjSxZc1p8EMDJQ6BJiO9kK8q2IKtJpGAiC0d8yf0k7uvuO1lzBf2RRVLUS0eQ7DWF/BBOrTgbNRXCtxC29vAzq3Bhkl3dKuRXtIZB5CwzBtub18X61dbxeBb4ddjDf3XF4mYMETCzxRqlVtd00Qmwut1dBdBG82O5GkLGb+wnQeC9Y8nYG/ZjGDVsSGpAFk9XJf9V2WyXhnt1qeaDnc5HvwUvx8ptFHYs51hLtE+pEajihbC+EhCGyIjykMpF+oTL8XJaAfRL8ewaiAedjBf1BbiXze7Nd+jYL3mmLZcFzNurYxmYWuqGpUAoYIy5t4aRskKyyRyyEXXSs4l4SaEv8dRSJpBlAaonRf0wNlzJuEx0/Mf3opZfc7HZgSVW3fJau3p7JpF+prKX0CI7zpRA95EAaFLzN/Yqza32mQTO5FHqDn8iakoBKXEbw2SVjnZRHnM5YjbJgNHoAmSaq2+9IWet3e0xgZOXAESnyCBg3CtPR8pdzWQ6fCqujSBUfztBOBV/rFdxTCx5jKk2lzp120elNDvIKHrgZprQtwu5j46SuJZv7Bzt9I9XYqFiGqZF6S6i79r6WQhjIXzy8FWVeyVwE2KoR4PvZoeEmnNbAEeKAfdH+xETHnNe8WHIctaEkssEBWt83+c71GJmW/HEAOGGWWoK290TAwUfsQ4XUp85mT0Sm24RdaNLp+JgYr7xtht6nmUahynJAsEMCGGBVKy2Rnp7ZhhJhHsTqXIBum8F8ibV0q/v9/WCygU3Yukv+ky6XCA/X07FRndhpXuRmHWdUR+C6rnI8gQFdgkg34FXDYcD7C6yu5NW/VossZwHV5bkwBdZ6A5fXSO+I42R+uiXJwqEthl4Rid6oU/4J1c8Vu+aIQNcQ1kvO/SHee5NPyzM9s3b8HeTnFJfcdlCfBiA4C6Y/muNhkPPFPAUazx2JHuvbDXwHcAy6vXKNbt0JGX9UkDVlVTgMKeKv3vstzN0svaDLsE1/SucAG36nCmhJXIdLQpea8Psd7CPA5b7TPCnOxUlkQDXV6ZPDdZNfjSpyIwgRHDN4HXBrD7w7kyJcYp2GdBSMyWkcGp8NlP8KkEeOlXGGTJnihEWcb8Qim04oHHrLMFryPJrZKJTTr/2dVvhwlov4bT5SSbDoGQioSJ";
		
		File file=new File("D:\\test\\soFile.txt");
		BufferedReader reader=new BufferedReader(new FileReader(file));
		
		String content=reader.readLine();
		reader.close();
		
		String result=decrypt(data,"b4c656e98e6bd0d7", "d4e03524d09d544a");
		System.out.println(result);
	}
    
	
}
